/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name          : freertos.c
 * Description        : Code for freertos applications
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "tft_drv.h"
#include "tft_gui.h"

#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId SystemHandle;
osThreadId DisplayHandle;
osThreadId LvglHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void SystemTask(void const *argument);
void DisplayTask(void const *argument);
void LvglTick(void const *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
{
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
    *ppxIdleTaskStackBuffer = &xIdleStack[0];
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
    /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
 * @brief  FreeRTOS initialization
 * @param  None
 * @retval None
 */
void MX_FREERTOS_Init(void)
{
    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* USER CODE BEGIN RTOS_MUTEX */
    /* add mutexes, ... */
    /* USER CODE END RTOS_MUTEX */

    /* USER CODE BEGIN RTOS_SEMAPHORES */
    /* add semaphores, ... */
    /* USER CODE END RTOS_SEMAPHORES */

    /* USER CODE BEGIN RTOS_TIMERS */
    /* start timers, add new ones, ... */
    /* USER CODE END RTOS_TIMERS */

    /* USER CODE BEGIN RTOS_QUEUES */
    /* add queues, ... */
    /* USER CODE END RTOS_QUEUES */

    /* Create the thread(s) */
    /* definition and creation of System */
    osThreadDef(System, SystemTask, osPriorityAboveNormal, 0, 128);
    SystemHandle = osThreadCreate(osThread(System), NULL);

    /* definition and creation of Display */
    osThreadDef(Display, DisplayTask, osPriorityNormal, 0, 2048);
    DisplayHandle = osThreadCreate(osThread(Display), NULL);

    /* definition and creation of Lvgl */
    osThreadDef(Lvgl, LvglTick, osPriorityNormal, 0, 128);
    LvglHandle = osThreadCreate(osThread(Lvgl), NULL);

    /* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
    /* USER CODE END RTOS_THREADS */
}

/* USER CODE BEGIN Header_SystemTask */
/**
 * @brief  Function implementing the System thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_SystemTask */
void SystemTask(void const *argument)
{
    /* USER CODE BEGIN SystemTask */
    printf("SystemTask init. \r\n");
    /* Infinite loop */
    for (;;)
    {
        osDelay(1000);
    }
    /* USER CODE END SystemTask */
}

/* USER CODE BEGIN Header_DisplayTask */
/**
 * @brief Function implementing the Display thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_DisplayTask */
void DisplayTask(void const *argument)
{
#if 1
    /* USER CODE BEGIN DisplayTask */
    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();

    lv_obj_t *switch_obj = lv_switch_create(lv_scr_act());
    lv_obj_set_size(switch_obj, 60, 30);
    lv_obj_align(switch_obj, LV_ALIGN_CENTER, 0, 0);

    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_text_color(&style, lv_color_hex(0xFF0000));

    lv_obj_t *label_obj = lv_label_create(lv_scr_act());
    // lv_obj_set_style_text_font(label_obj, &lv_font_montserrat_24, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_add_style(label_obj, &style, LV_PART_MAIN);
    lv_obj_set_pos(label_obj, 0, 0);
    lv_label_set_long_mode(label_obj, LV_LABEL_LONG_SCROLL_CIRCULAR);                       //滚动模式
    lv_obj_set_size(label_obj, 128, 28);
    lv_label_set_text(label_obj, "Hello LVGL! \n123 mA");


    /* Infinite loop */
    for (;;)
    {
        osDelay(5);
        lv_timer_handler();
        // HAL_GPIO_TogglePin(TFT_BLK_GPIO_Port, TFT_BLK_Pin);
        {
            static uint8_t print_cnt = 0;
            if (++print_cnt >= 200)
            {
                print_cnt = 0;
                printf("Display runing. \r\n");
            }
        }
    }
    /* USER CODE END DisplayTask */
#else
    /* USER CODE BEGIN DisplayTask */
    TFT_Init();
    TFT_Clear(ST7735_BLACK);
    TFT_GUI_Circle(50, 50, 10, ST7735_YELLOW);
    TFT_DrawPoint(100, 100, ST7735_GREEN);
    TFT_DrawPoint(110, 110, ST7735_YELLOW);
    osDelay(1000);
    /* Infinite loop */
    for (;;)
    {
        osDelay(1000);
        ST7735_DrawRectangle(0, 0, 20, 40, ST7735_YELLOW);
        printf("Display RED. \r\n");
        osDelay(1000);
        ST7735_DrawRectangle(0, 0, 20, 40, ST7735_GREEN);
        printf("Display GREEN. \r\n");
        osDelay(1000);
        ST7735_DrawRectangle(0, 0, 20, 40, ST7735_BLUE);
        printf("Display BLUE. \r\n");
    }
    /* USER CODE END DisplayTask */
#endif
}

/* USER CODE BEGIN Header_LvglTick */
/**
 * @brief Function implementing the Lvgl thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_LvglTick */
void LvglTick(void const *argument)
{
    /* USER CODE BEGIN LvglTick */

    /* Infinite loop */
    for (;;)
    {
        osDelay(10000);
    }
    /* USER CODE END LvglTick */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */
